%% Author: Sunny
%% Created: 2011-7-25
%% Description: get vncport
-module(vncport).
-date("2011.07.25").  

%%
%% Include Files
%%
-include_lib("stdlib/include/qlc.hrl").
-record(vnc_counter,
				{
				vncport_num,
				used_flag
				}).

%%
%% Exported Functions
%%
-export([init/0, stop/0]).
-export([recovery_one_vncport/1]).
-export([get_next_vncport/0]).

%%
%% Api Functions
%%
init() ->
%	mnesia:stop(),
%	mnesia:delete_schema([node()]),
%	mnesia:create_schema([node()]),
%	mnesia:start(),
	mnesia:create_table(vnc_counter,[{attributes, record_info(fields, vnc_counter)}]),
%	F = fun(N) ->
%			insert_to_table(N)
%		end,
%	for(5908, 5910, F),
%	for(5915, 5917, F),
	mnesia:dirty_update_counter(vnc_counter, mac_id, 5900).

stop() ->
	mnesia:stop().

get_next_vncport() ->
	Query = qlc:q([X#vnc_counter.used_flag || X <- mnesia:table(vnc_counter),
					X#vnc_counter.vncport_num =:= mac_id]),
	F = fun() ->
			qlc:e(Query)
	end,
	io:format("get the vncport which is not used~n"), %% degug info
	{atomic, [Result]} = mnesia:transaction(F),
%	spawn(fun() -> update_vnc_counter(Result) end),
	update_vnc_counter(Result),
	io:format("get the next vncport is:~p~n", [Result]), %% debug info
	Result.

recovery_one_vncport(N) ->
	Row = {vnc_counter, N},
	F = fun() ->
		mnesia:delete(Row)
	end,
	Result = mnesia:transaction(F),
	io:format("delete ~p successfully~n", [N]), %% debug info
	Result.

%%
%% Local Functions
%%
update_vnc_counter(X) ->
	io:format("spawn one process to update vnc_counter~n"), %% debug info
	insert_to_table(X),
%	Query = #vnc_counter{vncport_num=X, used_flag=yes},
%	F = fun() ->
%			mnesia:write(Query)
%		end,
%	mnesia:transaction(F),
	io:format("add one used vncport to vnc_counter successfully!~n"), %% debug info
	if
		X+1 > 65535 ->
			N=5900;
		X+1 =< 65535 ->
			N=X+1
	end,
	io:format("now begin check whether in vnc_counter~n"), %% debug info
	case check_in_vnc_counter(N) of
		true ->
			io:format("find ~p is in vnc_counter~n", [N]), %% debug info
			NX = find_not_in_vnc_counter(N), %% find one not in vnc_counter
			Row = #vnc_counter{vncport_num=mac_id, used_flag=NX};
		false ->
			io:format("find ~p is not in vnc_counter~n", [N]), %% debug info
			Row = #vnc_counter{vncport_num=mac_id, used_flag=N}
	end,
	F = fun() ->
			mnesia:write(Row)
		end,
	mnesia:transaction(F),
	io:format("update vnc_counter over~n"), %% debug info
	ok.

check_in_vnc_counter(N) ->
	io:format("check ~p is or not in vnc_counter~n", [N]), %% debug info
	Query = qlc:q([X#vnc_counter.vncport_num || X <- mnesia:table(vnc_counter),
					X#vnc_counter.vncport_num =:= N]),
	F = fun() ->
			qlc:e(Query)
	end,
	Result = mnesia:transaction(F),
	io:format("check result is:~p~n", [Result]), %% debug info
	case Result of
		{atomic, []} ->
			Return = false;
		{atomic, [_]} ->
			Return = true
	end,
	Return.

find_not_in_vnc_counter(N) ->
	if
		N+1 > 65535 ->
			NX = 5900;
		N+1 =< 65535 ->
			NX = N+1
	end,
	case check_in_vnc_counter(NX) of
		true ->
			Result = find_not_in_vnc_counter(N+1);
		false ->
			Result = NX
	end,
	Result.

insert_to_table(N) ->
	Row = #vnc_counter{vncport_num=N, used_flag=yes},
	F = fun() ->
			mnesia:write(Row)
		end,
	mnesia:transaction(F).

for(Max, Max, F) ->
	[F(Max)];
for(Min, Max, F) ->
	[F(Min)|for(Min+1, Max, F)].
